﻿#include <iostream>
#include <string>
#include "boost/lexical_cast.hpp"
#include <hiredis.h>
#include "DistLock.h"
#include <thread>
#include <windows.h>
void TestRedis() {
    //连接redis 需要启动才可以进行连接
//redis默认监听端口为6387 可以再配置文件中修改
    redisContext* c = redisConnect("81.68.86.146", 6380);
    if (c->err)
    {
        printf("Connect to redisServer faile:%s\n", c->errstr);
        redisFree(c);        return;
    }
    printf("Connect to redisServer Success\n");

    std::string redis_password = "123456";
    redisReply* r = (redisReply*)redisCommand(c, "AUTH %s", redis_password.c_str());
    if (r->type == REDIS_REPLY_ERROR) {
        printf("Redis认证失败！\n");
    }
    else {
        printf("Redis认证成功！\n");
    }

    //为redis设置key
    const char* command1 = "set stest1 value1";

    //执行redis命令行
    r = (redisReply*)redisCommand(c, command1);

    //如果返回NULL则说明执行失败
    if (NULL == r)
    {
        printf("Execut command1 failure\n");
        redisFree(c);        return;
    }

    //如果执行失败则释放连接
    if (!(r->type == REDIS_REPLY_STATUS && (strcmp(r->str, "OK") == 0 || strcmp(r->str, "ok") == 0)))
    {
        printf("Failed to execute command[%s]\n", command1);
        freeReplyObject(r);
        redisFree(c);        return;
    }

    //执行成功 释放redisCommand执行后返回的redisReply所占用的内存
    freeReplyObject(r);
    printf("Succeed to execute command[%s]\n", command1);

    const char* command2 = "strlen stest1";
    r = (redisReply*)redisCommand(c, command2);

    //如果返回类型不是整形 则释放连接
    if (r->type != REDIS_REPLY_INTEGER)
    {
        printf("Failed to execute command[%s]\n", command2);
        freeReplyObject(r);
        redisFree(c);        return;
    }

    //获取字符串长度
    int length = r->integer;
    freeReplyObject(r);
    printf("The length of 'stest1' is %d.\n", length);
    printf("Succeed to execute command[%s]\n", command2);

    //获取redis键值对信息
    const char* command3 = "get stest1";
    r = (redisReply*)redisCommand(c, command3);
    if (r->type != REDIS_REPLY_STRING)
    {
        printf("Failed to execute command[%s]\n", command3);
        freeReplyObject(r);
        redisFree(c);        return;
    }
    printf("The value of 'stest1' is %s\n", r->str);
    freeReplyObject(r);
    printf("Succeed to execute command[%s]\n", command3);

    const char* command4 = "get stest2";
    r = (redisReply*)redisCommand(c, command4);
    if (r->type != REDIS_REPLY_NIL)
    {
        printf("Failed to execute command[%s]\n", command4);
        freeReplyObject(r);
        redisFree(c);        return;
    }
    freeReplyObject(r);
    printf("Succeed to execute command[%s]\n", command4);

    //释放连接资源
    redisFree(c);

}

int TestDisLock() {
    // 连接到 Redis 服务器（根据实际情况修改主机和端口）
    redisContext* context = redisConnect("81.68.86.146", 6380);
    if (context == nullptr || context->err) {
        if (context) {
            std::cerr << "连接错误: " << context->errstr << std::endl;
            redisFree(context);
        }
        else {
            std::cerr << "无法分配 redis context" << std::endl;
        }
        return 1;
    }

    std::string redis_password = "123456";
    redisReply* r = (redisReply*)redisCommand(context, "AUTH %s", redis_password.c_str());
    if (r->type == REDIS_REPLY_ERROR) {
        printf("Redis认证失败！\n");
    }
    else {
        printf("Redis认证成功！\n");
    }

    // 尝试获取锁（锁有效期 10 秒，获取超时时间 5 秒）
    std::string lockId = DistLock::Inst().acquireLock(context, "my_resource", 10, 5);
    
    if (!lockId.empty()) {
        std::cout << "子进程 " << GetCurrentProcessId() << " 成功获取锁，锁 ID: " << lockId << std::endl;
        // 执行需要保护的临界区代码
        std::this_thread::sleep_for(std::chrono::seconds(2));

        // 释放锁
        if (DistLock::Inst().releaseLock(context, "my_resource", lockId)) {
            std::cout << "子进程 " << GetCurrentProcessId() << " 成功释放锁" << std::endl;
        }
        else {
            std::cout << "子进程 " << GetCurrentProcessId() << " 释放锁失败" << std::endl;
        }
    }
    else {
        std::cout << "子进程 " << GetCurrentProcessId() << " 获取锁失败" << std::endl;
    }

    // 释放 Redis 连接
    redisFree(context);
}


int main()
{
    //TestRedis();
    TestDisLock();
    system("pause");
    return 0;
}